﻿using AutoMapper;
using Msung.Business.Model;
using Msung.Core;
using Msung.Repository.Entity;
using Msung.Repository.IRepository;
using DataTraceService.IService;
using Msung.Repository.IRepository.MSUNG;
using Msung.Core.Caching;
using Microsoft.Extensions.Logging;
using Msung.Business.IService;
using Msung.Business.Model.TRACER;
using DataTraceService.Model;
using Newtonsoft.Json;

namespace DataTraceService.Service
{
    public class TaskService : ITaskService
    {
        private readonly ILogger<TaskService> _logger;
        readonly IRedisOperationRepository _redisRepository;
        readonly IFlowcardService _flowService;
        readonly IWaferService _waferService;

        public TaskService(
            ILogger<TaskService> logger,
            IRedisOperationRepository redisRepository,
            IFlowcardService flowService,
            IWaferService waferService
            )
        {
            _logger = logger;
            _redisRepository = redisRepository;
            _flowService = flowService;
            _waferService = waferService;
        }
        /// <summary>
        /// 制绒上料任务
        /// </summary>
        /// <param name="model"></param>
        public void UpZrTask(BaseModel model)
        {
            BasketModel basket = CreateBasket(model);

            FlowCardInput flowInput = _flowService.CreateFlowCard(basket);
            basket.WorkOrder = flowInput.WORKORDER;
            basket.ProductCode = flowInput.MATERIAL;
            basket.FlowNo = flowInput.FLOWNO;
            basket.WaferList = flowInput.Wafers;

            //过站
            _flowService.FlowCardTrace(basket, flowInput);
        }
        /// <summary>
        /// 上料处理逻辑
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public void UpBasketTask(BaseModel model)
        {
            BasketModel basket = CreateBasket(model);

            string? flowNo = _redisRepository.Get($"FlowCard:{model.Struid}");
            flowNo = flowNo?.Replace("\"", "");

            FlowCardInput? flowInput = string.IsNullOrWhiteSpace(flowNo) ? null : _redisRepository.Get<FlowCardInput>("FlowNo:" + flowNo);
            string process = (int.Parse(model.Pid) - 1).ToString();
            if (flowInput == null || flowInput.CURRENTPROCESS != process || flowInput.UPDOWN != "2")
            {
                flowInput = _flowService.CreateFlowCard(basket);
            }

            int setCacheTime = _flowService.GetCacheMinutes(model.Pid);
            int cacheTime = (int)(model.CreatedTime - flowInput.CURRENTTIME).TotalMinutes;
            if (cacheTime > setCacheTime)
            {
                basket.Status = "4";
                basket.Remark = "外在制超时";
            }

            basket.WorkOrder = flowInput.WORKORDER;
            basket.ProductCode = flowInput.MATERIAL;
            basket.FlowNo = flowInput.FLOWNO;
            basket.WaferList = flowInput.Wafers;
            //过站
            _flowService.FlowCardTrace(basket, flowInput);
            _waferService.SaveWaferId(model.Pid, basket.FlowNo, model.WaferId);
            _logger.LogDebug(basket.FlowNo + ":" + JsonConvert.SerializeObject(model));
        }
        /// <summary>
        /// 切换下料花篮
        /// </summary>
        /// <param name="model"></param>
        public void DownBasketTask(BaseModel model)
        {
            BasketModel basket = CreateBasket(model);
            FlowCardInput? flowCard = GetFlowCard(model);
            //过站
            if (flowCard == null)
            {
                flowCard = _flowService.CreateFlowCard(basket);
            }

            basket.WorkOrder = flowCard.WORKORDER;
            basket.ProductCode = flowCard.MATERIAL;
            basket.FlowNo = flowCard.FLOWNO;
            basket.Buid = flowCard.STRUID;
            basket.WaferList = flowCard.Wafers;

            if (basket.WaferList.Where(m => m.ID == 0).Count() > 0)
            {
                for (int i = 0; i < basket.WaferList.Count; i++)
                {
                    if (basket.WaferList[i].ID == 0)
                    {
                        basket.WaferList[i] = _waferService.CreateWafer(basket, i);
                    }
                    basket.WaferList[i].TESTID = model.WaferId[i];
                }
            }
            _flowService.FlowCardTrace(basket, flowCard);
        }
        /// <summary>
        /// 制绒下料花篮
        /// </summary>
        /// <param name="model"></param>
        public void DownZrTask(BaseModel model)
        {
            BasketModel basket = CreateBasket(model);

            string? flowNo = _redisRepository.Get($"FlowCard:{model.Struid}");
            flowNo = flowNo?.Replace("\"", "");

            FlowCardInput? flowInput = string.IsNullOrWhiteSpace(flowNo) ? null : _redisRepository.Get<FlowCardInput>("FlowNo:" + flowNo);
            string process = (int.Parse(model.Pid) - 1).ToString();
            if (flowInput == null || flowInput.CURRENTPROCESS != process || flowInput.UPDOWN != "2")
            {
                flowInput = _flowService.CreateFlowCard(basket);
            }

            basket.WorkOrder = flowInput.WORKORDER;
            basket.ProductCode = flowInput.MATERIAL;
            basket.FlowNo = flowInput.FLOWNO;
            basket.WaferList = flowInput.Wafers;

            _flowService.FlowCardTrace(basket, flowInput);
        }

        /// <summary>
        /// 激光SE下料逻辑
        /// </summary>
        /// <param name="model"></param>
        public void DownRecipeTask(BaseModel model)
        {
            BasketModel basket = CreateBasket(model);
            var wafers = _waferService.SwitchedWafer(model.Pid, model.WaferId);
            FlowCardInput? flowCard = GetFlowCard(wafers, model.Pid, model.Eid, basket.ChannelNo.ToString());

            //过站
            if (flowCard == null)
            {
                _logger.LogDebug("WaferId获取失败：" + JsonConvert.SerializeObject(model));
                flowCard = _flowService.CreateFlowCard(basket);
                wafers = flowCard.Wafers;
            }
            else if (string.IsNullOrWhiteSpace(flowCard.FLOWNO))
            {
                flowCard = _flowService.CreateFlowCard(basket);
                flowCard.Wafers = wafers;
                basket.Status = "2";
            }

            basket.WorkOrder = flowCard.WORKORDER;
            basket.ProductCode = flowCard.MATERIAL;
            basket.FlowNo = flowCard.FLOWNO;
            basket.Buid = flowCard.STRUID;
            basket.WaferList = wafers.Count == 0 ? flowCard.Wafers : wafers;

            int newWafers = basket.WaferList.Where(m => m.ID == 0).Count();
            if (newWafers > 0)
            {
                int idx = 0;
                var createdWafers = _waferService.CreateWafers(basket, newWafers);
                for (int i = 0; i < basket.WaferList.Count; i++)
                {
                    if (basket.WaferList[i].ID == 0)
                    {
                        basket.WaferList[i] = createdWafers[idx];
                        basket.WaferList[i].SORT = i;
                        idx++;
                    }
                    basket.WaferList[i].TESTID = model.WaferId[i];
                }
            }

            _flowService.FlowCardTrace(basket, flowCard);
        }

        /// <summary>
        /// 获取WAFER对应流程卡
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private FlowCardInput GetFlowCard(List<TBL_TRACE_WAFER> wafers, string pid, string eid, string channel)
        {
            //从WAFERID内选择一个合适的花篮UID
            List<FlowCount> flowNos = wafers.OrderBy(m => m.CURRENTTIME)
                .GroupBy(m => m.FLOWNO).Select(m => new FlowCount() { FlowNo = m.Key, Qty = m.Count() })
                .Where(m => m.Qty > 20).ToList();
            if (flowNos.Count == 1 && string.IsNullOrWhiteSpace(flowNos[0].FlowNo))
            {
                return null;
            }

            List<FlowCardInput> flows = new List<FlowCardInput>();
            FlowCardInput? flowCard = null;
            foreach (var item in flowNos)
            {
                if (string.IsNullOrWhiteSpace(item.FlowNo))
                {
                    continue;
                }
                flowCard = _redisRepository.Get<FlowCardInput>($"FlowNo:{item.FlowNo}");

                if (flowCard == null)
                {
                    _logger.LogDebug($"未读到流程卡：{item.FlowNo}");
                    continue;
                }
                if (flowCard.CURRENTPROCESS == pid && flowCard.UPDOWN == "0")
                {
                    flows.Add(flowCard);
                }
            }
            if (flows.Count == 0)
            {
                flowCard = _flowService.GetCatchFlowNo(pid, eid, channel);
                if (flowCard == null)
                {
                    flowCard = new FlowCardInput();
                }
            }
            else
            {
                flowCard = flows.FirstOrDefault();
                flows.Remove(flowCard);
                _flowService.RemoveCacheTimeOut(pid, eid, channel, flowCard.FLOWNO);
                foreach (var item in flows)
                {
                    _flowService.AddCache(eid, channel, item.FLOWNO);
                }
            }
            return flowCard;
        }
        private FlowCardInput? GetFlowCard(BaseModel model)
        {
            FlowCardInput? flowCard = null;
            foreach (var item in model.WaferId)
            {
                string redisKey = $"TUBE_WAFER:{model.Pid}-{item}";
                string value = _redisRepository.Get(redisKey);
                if (string.IsNullOrWhiteSpace(value)) continue;
                value = value.Replace("\"", "");

                //从WAFERID内选择一个合适的花篮UID
                flowCard = _redisRepository.Get<FlowCardInput>("FlowNo:" + value);
                if (flowCard == null || (DateTime.Now - flowCard.CURRENTTIME).TotalMinutes < 60)
                {
                    _logger.LogDebug($"未读到流程卡：{item}");
                    continue;
                }
                if (flowCard.CURRENTPROCESS == model.Pid && flowCard.UPDOWN == "0")
                {
                    break;
                }
                else
                {
                    flowCard = null;
                }
            }
            _waferService.RemoveRedisWaferKey(model.Pid, model.WaferId);
            return flowCard;
        }

        private BasketModel CreateBasket(BaseModel model)
        {
            BasketModel basket = new BasketModel()
            {
                Eid = model.Eid,
                Pid = model.Pid,
                Struid = model.Struid,
                BoatNo = model.BoatNo,
                GrooveNo = model.GrooveNo,
                TubeNo = model.TubeNo,
                ChannelNo = int.Parse(model.Chanel),
                UpDown = model.UpDown,
                ProcessTime = model.CreatedTime,
                Status = "0"
            };
            return basket;
        }
    }
}
